package com.framework.macros;

import java.util.Calendar;
import java.util.Date;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.ext.AfterCompose;
import org.zkoss.zul.Column;
import org.zkoss.zul.Columns;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Intbox;
import org.zkoss.zul.Label;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Popup;
import org.zkoss.zul.Row;
import org.zkoss.zul.Rows;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Window;

public class CampoMesMacro extends Textbox implements AfterCompose {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
//	private static Logger log = Logger.getLogger(CampoMesMacro.class);
	private Popup popupObservaciones = null;

	private Window window;
	private Textbox textbox;

	private OnCambioTexto onCambioTexto;
	private Intbox intboxAnio;
	private Listbox listMes;
	
	private OnFechaCambia onFechaCambia;
	
	public static String[] meses = {"ENERO","FEBRERO","MARZO","ABRIL","MAYO","JUNIO","JULIO","AGOSTO","SEPTIEMBRE","OCTUBRE","NOVIEMBRE","DICIEMBRE"};
	
	
	private int anio;
	private int mes;
	
	private String separador = "-";

	public CampoMesMacro(Window window) {
		this.window = window;
		afterCompose();
	}

	public CampoMesMacro() {
		reiniciar();
	}
 
	private void inicializarMesYAnio() {
		anio = getAnio();
		mes = getMes();
	}
	
	
	public void reiniciar(){
		inicializarMesYAnio();
		cargarValorInicial();
	}
 

	@Override
	public void afterCompose() {
		setReadonly(true);
		setTooltiptext("por favor, presionar para desplegar el campo..!!");
		addEventListener(Events.ON_CLICK, new EventListener<Event>() {
			@Override
			public void onEvent(Event event) throws Exception {
				//log.info("@onEvent cargando el evento.");
				if (popupObservaciones == null)
					popupObservaciones = generarpopUp();
				popupObservaciones.open(CampoMesMacro.this, "after_end");
				popupObservaciones.focus();
				//log.info("@onEvent despues de cargar el evento.");
			}
		});
	}

	/**
	 * Este metodo se encarga de generar el popup
	 * 
	 * @author Luis Miguel Hernandez
	 * */
	protected Popup generarpopUp() {
		final Popup popup = new Popup();
		
		popup.addEventListener(Events.ON_OPEN, new EventListener<Event>() {
			@Override
			public void onEvent(Event event) throws Exception {
				intboxAnio.setValue(anio);
				listMes.setSelectedIndex(mes); 
			}
		});
		
		Window window = new Window(){
			@Override
			public void onClose() {
				super.onClose();
				popup.close();
			}
		};
//		window.setTitle("seleccione mes");
		window.setWidth("200px");
		window.appendChild(crearTabla());
		popup.appendChild(window);
		getPage().getFirstRoot().appendChild(popup);
		return popup;
	}
 
	private Grid crearTabla() {
		Grid grid = new Grid();
		
		/* columnas */
		Columns columns = new  Columns();
		Column column = new Column();
		column.setWidth("50px"); 
		columns.appendChild(column);
		columns.appendChild(new Column());
		columns.setVisible(false);
		grid.appendChild(columns);
		
		/* contenido */
		Rows rows = new Rows();
		Row row = new Row();
		
		/* anio */
		row.appendChild(new Label("año:"));
		intboxAnio = new Intbox(anio);
		intboxAnio.setHflex("1");  
		addEvent(intboxAnio, Events.ON_BLUR); 
		
		row.appendChild(intboxAnio);
		rows.appendChild(row);
		
		/* mes */
		row = new Row();
		row.appendChild(new Label("Mes"));
		listMes = new Listbox();
		listMes.setHflex("1");
		listMes.setMold("select");
		listMes.setSclass("combobox"); 
		addEvent(listMes, Events.ON_SELECT); 
		inicializarMeses(); 
		row.appendChild(listMes);
		rows.appendChild(row);
		
		grid.appendChild(rows);
		return grid;
	} 
	
	
	private void addEvent(Component component, String event){
		component.addEventListener(event, new EventListener<Event>() {
			@Override
			public void onEvent(Event arg0) throws Exception {
				anio = validarAnio(intboxAnio.getValue());
				mes = listMes.getSelectedItem().getValue();
				cargarValorInicial();
				if(onFechaCambia != null){
					onFechaCambia.fechaCambio(CampoMesMacro.this);
				}
			}
		});
	}
	
	
	private void cargarValorInicial(){
		CampoMesMacro.this.setValue(meses[mes] + separador + anio);
	}
 
	private void inicializarMeses() {
		for (int i = 0; i < meses.length; i++) {
			String mes = meses[i];
			listMes.appendChild(new Listitem(mes, i)); 
		}
		if(listMes.getItemCount() > 0){
			listMes.setSelectedIndex(mes); 
		}
	}
	
	
	/**
	 * Este metodo me valida el año correcto
	 * */
	private int validarAnio(Integer anio){
		if(anio == null) return getAnio();
		else{
			if(anio.intValue() >= getAnioMin() && anio.intValue() <= getAnioMax()){
				return anio;
			}else
			   return getAnio();
		}
	}

	private int getAnio() {
		return Calendar.getInstance().get(Calendar.YEAR);
	}
	
	private int getMes() {
		return Calendar.getInstance().get(Calendar.MONTH);
	}
	
	
	private int getAnioMax() {
		return 2200;
	}
	
	private int getAnioMin() {
		return 2000;
	}
	

	@Override
	public void setText(String value) throws WrongValueException {
		super.setText(value);
		if (textbox != null) {
			textbox.setValue(value);
		}
	}

	public Window getWindow() {
		return window;
	}

	public void setWindow(Window window) {
		this.window = window;
	}

	public OnCambioTexto getOnCambioTexto() {
		return onCambioTexto;
	}

	public void setOnCambioTexto(OnCambioTexto onCambioTexto) {
		this.onCambioTexto = onCambioTexto;
	}
	
	
	public void setDate(Date value) {
		if(value != null){
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(value);
			anio =  calendar.get(Calendar.YEAR);
			mes  =  calendar.get(Calendar.MONTH);
			cargarValorInicial();
		}
	}
	
	public Date getDate(){
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.MONTH, 1);
		calendar.set(Calendar.MONTH, mes);
		calendar.set(Calendar.YEAR, anio);
		return calendar.getTime();
	}
	
	public Date getDateFinal(){
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1); 
		calendar.set(Calendar.MONTH, mes);
		calendar.set(Calendar.YEAR, anio);
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		return calendar.getTime();
	}

	
	/**
	 * Esta interface es el evento cuando el texto cambia
	 * 
	 * @author Luis Miguel
	 * */
	public interface OnCambioTexto {
		void texto(String texto);
	}

	public String getSeparador() {
		return separador;
	}

	public void setSeparador(String separador) {
		this.separador = separador;
	}
	
	
	public interface OnFechaCambia{
		void fechaCambio(CampoMesMacro campoMesMacro);
	}

	public OnFechaCambia getOnFechaCambia() {
		return onFechaCambia;
	}

	public void setOnFechaCambia(OnFechaCambia onFechaCambia) {
		this.onFechaCambia = onFechaCambia;
	}
}
